Hello electron

其实在从事前端工作后不久就知道了 electron,当时就感叹 javascript 的强大,从最基础的 web 应用到 cordova 到跨平台移动应用,在到 electron 跨平台的桌面应用.但是也只是知道了这个名字以及 electron 可以做什么的一个简单了解.

直到前段时间,一个普通朋友问我能不能帮忙做一个档案统计的小工具.通过基本了解后,才知道他们的需求:公司有很多档案(每一份档案都按照一定格式存为了 word 文档),现在要对这些档案进行一个整理和统计,最终汇总到 excel 里面,后续再根据具体到需要进行统计分析.

其实我第一时间想到到是用 node 服务器来处理 word 文档并将得到到数据存入数据库,也方便后续对数据的一些操作.但是后面又了解到这个程序是在他们公司内网安装使用,而公司内网安装服务器环境是一个难题(毕竟他自己又不会,我也进不去).想了一下,可以用 electron 做个桌面程序,直接使用 node 的 api 来做,只是不能将数据存到数据库了,不过存到 excel 也随时可以导入数据库.

main

我是在 electron demo 的基础做的,所以直接 clone 的 electron-quick-start

1
2
3
4
git clone https://github.com/electron/electron-quick-start.git
cd electron-quick-start
npm install
npm start

然后就可以看到项目启动了,当然我加了两个按钮.
201907301900.png

然后我们可以看到熟悉到 index.html 文件,由于我需要到功能很简单,所以我是直接在 index.html 里面编辑的,如果功能复杂的话可以写成多个页面或者做成 spa.

然后可以直接在 html 的 js 中写 nodejs 的代码,因为最终的运行环境就是在 node 的环境下,不需要担心环境的问题.上传文件我们用到了 dialog 组件.然后读取 word 使用了 mammoth 插件、导出 excel 使用了 excel-export 插件,实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
let keys = [
"岗位名称",
"所属部门",
"岗位编号",
"工作地点",
"直接上级岗位",
"直接下级岗位",
"直接下属人数",
"间接下属人数",
"工作经验",
"专业资质证明",
"知识与技能",
"关键素质项",
"其他要求",
];

let text;
let excel;
let filePaths;
const fs = require("fs");
const mammoth = require("mammoth");
const excelPort = require("excel-export");
const { dialog } = require("electron").remote;

// 读取word
const readWord = function (words, analysis) {
return new Promise((resolve) => {
mammoth
.extractRawText({ path: words[analysis.length] })
.then(async function (result) {
let error = result.messages.toString();
if (error) {
analysis.push("error");
} else {
analysis.push(result.value);
}
if (analysis.length !== words.length) {
await readWord(words, analysis);
resolve(analysis);
} else {
resolve(analysis);
}
});
});
};

// 选择文件
document.getElementById("file").addEventListener("click", function () {
try {
dialog.showOpenDialog(
{
properties: ["openFile", "multiSelections"],
},
function (files) {
filePaths = files;
filePaths.map((item) => {
let fileName = document.createElement("p");
let laseIndex = item.lastIndexOf("/") + 1;
fileName.className = "file";
fileName.innerText = item.substring(laseIndex);
document.getElementById("files").append(fileName);
});
}
);
} catch (e) {
dialog.showErrorBox("title", e.message);
}
});

// 解析word文档
document.getElementById("btn").addEventListener("click", async function () {
try {
let files = document.querySelectorAll(".file");
let analysis = await readWord(filePaths, []);
analysis = analysis.map((item, index) => {
if (item === "error") {
let icon = document.createElement("span");
icon.innerText = "error";
icon.style.color = "red";
files[index].append(icon);
return item;
} else {
let newItem = new Array();
let temp = item.split("\n\n");
keys.forEach((item) => {
let index = temp.indexOf(item);
if (index !== -1) {
newItem.push(temp[index + 1]);
}
});
let icon = document.createElement("span");
icon.innerText = "ok";
icon.style.color = "green";
files[index].append(icon);
return newItem;
}
});
let config = {
cols: keys.map((item) => ({ caption: item })),
rows: analysis.filter((item) => Array.isArray(item)),
};
excel = excelPort.execute(config);
} catch (e) {
dialog.showErrorBox("title", e.message);
}
});

// 导出excel
document.getElementById("export").addEventListener("click", function () {
dialog.showSaveDialog(
{
title: "导出到",
filters: [{ name: "excel", extensions: ["xlsx"] }],
},
function (path) {
fs.writeFile(path, excel, "binary", function (err) {
if (err) {
dialog.showErrorBox("title", e.message);
}
});
}
);
});

这个项目也只是在官方 demo 的基础上做了简单的改造,也简单的走了一下 electron 的开发流程,对 electron 有了更多对了解.

项目地址: https://github.com/qiangqiang93/word-to-excel

[越努力,越幸运!]